package com.jinxiangyang.controller;


import com.jinxiangyang.annotation.OperateLog;
import com.jinxiangyang.domain.Video;
import com.jinxiangyang.service.VideoService;
import com.jinxiangyang.utils.enums.BusinessType;
import com.jinxiangyang.utils.enums.OperatorType;
import com.jinxiangyang.utils.result.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;

/**
 * <p>
 * 课程视频 前端控制器
 * </p>
 *
 * @author jinxiangyang
 * @since 2023-08-12
 */
@RestController
@RequestMapping("/video")
@Api(tags = "课程视频")
public class VideoController {

    @Autowired
    private VideoService videoService;


    @GetMapping("get/{id}")
    @ApiOperation("根据id进行查询")
    @OperateLog(title = "课程视频", operatorType = OperatorType.STUDENT, businessType = BusinessType.OTHER)
    public AjaxResult get(@PathVariable Long id){
        Video video = videoService.getById(id);
        return AjaxResult.success(video);
    }


    @ApiModelProperty("分页接口")
    @GetMapping("{pageNumber}/{pageSize}")
    @OperateLog(title = "课程视频", operatorType = OperatorType.STUDENT, businessType = BusinessType.OTHER)
    public AjaxResult getVideoListPage(@PathVariable Integer pageNumber,@PathVariable Integer pageSize, Video video){
        Map<String, Object> listVideoPage = videoService.getListVideoPage(pageNumber, pageSize, video);
        return AjaxResult.success(listVideoPage);
    }



    @ApiModelProperty("删除接口")
    @DeleteMapping("/{id}")
    @OperateLog(title = "课程视频", operatorType = OperatorType.TEACHER, businessType = BusinessType.DELETE)
    public AjaxResult deleteVideo(@PathVariable("id") Long id){
        return videoService.removeById(id)?AjaxResult.success():AjaxResult.error("删除失败");
    }


    @ApiModelProperty("插入接口")
    @PostMapping
    @OperateLog(title = "课程视频", operatorType = OperatorType.TEACHER, businessType = BusinessType.INSERT)
    public AjaxResult insertVideo(@RequestBody Video video){
        return videoService.save(video)?AjaxResult.success():AjaxResult.error("插入失败");
    }



    @PutMapping
    @ApiModelProperty("视频上传接口")
    @OperateLog(title = "课程视频", operatorType = OperatorType.TEACHER, businessType = BusinessType.UPDATE)
    public AjaxResult updateVideo(@RequestBody Video video){
        return videoService.updateById(video)?AjaxResult.success():AjaxResult.error("插入失败");
    }


   @PostMapping("/save")
   @ApiOperation("添加课程信息")
   @OperateLog(title = "课程信息", operatorType = OperatorType.TEACHER, businessType = BusinessType.INSERT)
    public AjaxResult save(@RequestBody Video video){
        videoService.save(video);
        return AjaxResult.success();
    }

    @DeleteMapping("/delete/{id}")
    @ApiOperation("根据id进行删除")
    @OperateLog(title = "课程信息", operatorType = OperatorType.TEACHER, businessType = BusinessType.DELETE)
    public AjaxResult delete(@PathVariable Long id){
        videoService.removeById(id);
        return AjaxResult.success();
    }

    @PutMapping("/update")
    @ApiOperation("根据id进行修改")
    @OperateLog(title = "课程信息", operatorType = OperatorType.TEACHER, businessType = BusinessType.DELETE)
    public AjaxResult update(@RequestBody Video video){
        videoService.updateById(video);
        return AjaxResult.success();
    }
    @GetMapping("/getVideoSizeById/{videoId}")
    @ApiModelProperty("获取视频文件大小接口")
    @OperateLog(title = "视频课程信息", operatorType = OperatorType.TEACHER, businessType = BusinessType.OTHER)
    public long getVideoSizeById(@PathVariable("videoId") Integer videoId) throws IOException
    {
        Video videoPathList = videoService.getById(videoId);
        String videoPathUrl = videoPathList.getVideoUrl();
        Path filePath = Paths.get(videoPathUrl);
        if (Files.exists(filePath))
        {
            return Files.size(filePath);
        }
        return 0L;
    }



    @GetMapping("/policemen/{videoId}")
    @ApiModelProperty("点播")
    @CrossOrigin
    @OperateLog(title = "课程信息", operatorType = OperatorType.STUDENT, businessType = BusinessType.OTHER)
    public void videoPreview(HttpServletRequest request, HttpServletResponse response, @PathVariable("videoId") Integer videoId) throws Exception
    {
        System.out.println(videoId);
        Video videoPathList = videoService.getById(videoId);
        String videoPathUrl = videoPathList.getVideoUrl();
        Path filePath = Paths.get(videoPathUrl);
        if (Files.exists(filePath))
        {
            String mimeType = Files.probeContentType(filePath);
            if (StringUtils.hasText(mimeType))
            {
                response.setContentType(mimeType);
            }
            response.setHeader("Accept-Ranges", "bytes");
            long startByte = 0;
            long endByte = Files.size(filePath) - 1;
            String rangeHeader = request.getHeader("Range");
            if (rangeHeader != null && rangeHeader.startsWith("bytes="))
            {
                String[] range = rangeHeader.substring(6).split("-");
                startByte = Long.parseLong(range[0]);
                if (range.length == 2)
                {
                    endByte = Long.parseLong(range[1]);
                }
            }

            long contentLength = endByte - startByte + 1;
            response.setHeader("Content-Length", String.valueOf(contentLength));
            response.setHeader("Content-Range", "bytes " + startByte + "-" + endByte + "/" + Files.size(filePath));
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
            ServletOutputStream outputStream = response.getOutputStream();
            try (RandomAccessFile file = new RandomAccessFile(filePath.toFile(), "r"); FileChannel fileChannel = file.getChannel())
            {
                fileChannel.transferTo(startByte, contentLength, Channels.newChannel(outputStream));
            } finally
            {
                outputStream.close();
            }
        } else
        {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
        }
    }
}

